package agenda

object PersonalEntry {
  def hasValidSlots(slots: Array[Int]): Boolean = {
    if (slots == null)
      return false
    for (i <- 0 to (slots.length - 1)) {
      if (SlottedEntry.isValidSlot(slots(i)))
        return true
    }
    return false
  }
}

class PersonalEntry(_agenda: Agenda, _day: Int, _subject: String, isOccupying: Boolean, _slots: Int*) extends SlottedEntry(_agenda, _day, _subject) with Occupiable {

  private val slots: Array[Boolean] = new Array[Boolean](SlottedEntry.HIGHEST_SLOT - SlottedEntry.LOWEST_SLOT + 1)

  require(PersonalEntry.hasValidSlots(_slots.toArray))
  isOccupying_(isOccupying)
  for (i <- 0 to (_slots.length - 1)) {
    if (SlottedEntry.isValidSlot(_slots(i)))
      occupySlot(_slots(i))
  }

  override def isOccupying_ (isOccupying : Boolean) {
	  if(!isTerminated())
	 	  _isOccupying = isOccupying
  }

  override def occupiesSlot(slot: Int): Boolean = {
    SlottedEntry.isValidSlot(slot) && slots(slot - 1)
  }

  def occupySlot(slot: Int) {
    require(SlottedEntry.isValidSlot(slot))
    slots(slot - 1) = true
  }

  def freeSlot(slot: Int): Unit = {
    require(SlottedEntry.isValidSlot(slot))
    require((slot != getFirstSlot()) || getFirstSlot() != getLastSlot())
    slots(slot - 1) = false
  }

  override def mergeWith(other: Entry): PersonalEntry = {
    require(other != null)
    require(this.day == other.day)
    require(!this.isTerminated() && !other.isTerminated())
    require(this.agenda == other.agenda)
    require(other.isInstanceOf[PersonalEntry])
    val otherPersonalEntry: PersonalEntry = other.asInstanceOf[PersonalEntry]
    this.subject = (this.subject + other.subject)
    isOccupying_(this.isOccupying || otherPersonalEntry.isOccupying)
    for (i <- otherPersonalEntry.getFirstSlot() to otherPersonalEntry.getLastSlot()) {
      if (otherPersonalEntry.occupiesSlot(i))
        this.occupySlot(i)
    }
    other.terminate()
    return this
  }
}